package com.sg.business.patch01.adminfunction;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.bson.types.ObjectId;
import org.eclipse.swt.widgets.Display;

import com.bizvpm.bi.model.DataModel;
import com.bizvpm.bi.model.DataSet;
import com.bizvpm.bi.model.ExtractorEntry;
import com.bizvpm.bi.model.IAttributeColumn;
import com.bizvpm.bi.model.ICalculateColumn;
import com.mobnut.admin.IFunctionExcutable;
import com.mobnut.commons.Commons;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;

public class MapReduceTest implements IFunctionExcutable {

	@Override
	public void run() {
		DataModel dm1 = new DataModel("demo.datamodel.omsalesincome");
		DataModel dm2 = new DataModel("demo.datamodel.omsalesincome");

		final Map<String, List<ExtractorEntry>> extracts = new HashMap<String, List<ExtractorEntry>>();
		List<ExtractorEntry> entry = new ArrayList<ExtractorEntry>();
		entry.add(new ExtractorEntry("c2016001", "2016001"));
		entry.add(new ExtractorEntry("c2015001", "2015001"));
		extracts.put("c01", entry);

		entry = new ArrayList<ExtractorEntry>();
		entry.add(new ExtractorEntry("c2016002", "2016002"));
		entry.add(new ExtractorEntry("c2015002", "2015002"));
		extracts.put("c02", entry);

		final DBObject query = new BasicDBObject();
		query.put(
				"dept",
				new BasicDBObject().append("$in", new ObjectId[] {
						new ObjectId("52720645e5abc5e5ab578fbd"),
						new ObjectId("52720645e5abc5e5ab578efa") }));
		// query = null;
		final List<String> features = new ArrayList<String>();
		features.add("dept");
		features.add("market");
//		features.add("customer");

		final List<ICalculateColumn> calculates = new ArrayList<ICalculateColumn>();
		calculates.add(new ICalculateColumn() {

			@Override
			public String getColumnName() {
				return "sum";
			}

			@Override
			public Object getValue(Object[] values) {
				double value = 0;
				for (int i = 0; i < values.length; i++) {
					if (values[i] != null) {
						value = value + ((Number) values[i]).doubleValue();
					}
				}
				return value;
			}

		});

		final List<IAttributeColumn> attributes = new ArrayList<IAttributeColumn>();
		attributes.add(new IAttributeColumn() {

			@Override
			public String getColumnName() {
				return "desc";
			}

			@Override
			public Object getValue(String name, Object value) {
				return name + value;
			}


		});

		// long start, end;
		// start = System.currentTimeMillis();
		final Display display = Display.getCurrent();

		final DataSet ds = new DataSet("1");
		ds.addDataModel(dm1);
		ds.addDataModel(dm2);

		ds.setDisplay(display);

		ds.setAttributes(attributes);

		ds.setCalculates(calculates);

		ds.setExtracts(extracts);

		ds.setFeatures(features);

		ds.setQuery(query);

		for (int i = 0; i < 1; i++) {
			final int number = i;
			Thread t = new Thread(new Runnable() {
				@Override
				public void run() {
					try {
						if (number % 2 == 0) {
							printResult(ds, "result" + number);
						} else {
							printResult(ds, "result" + number);
						}
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			});
			t.start();
		}

		// final Map<String, Object> extract = new HashMap<String, Object>();
		// extract.put("c2014001", "2014001");
		// extract.put("c2014002", "2014002");
		// extract.put("c2014003", "2014003");
		// extract.put("c2014004", "2014004");
		// extract.put("c2014005", "2014005");
		// extract.put("c2014006", "2014006");
		// extract.put("c2014007", "2014007");
		// extract.put("c2014008", "2014008");
		// extract.put("c2014009", "2014009");
		// extract.put("c2014010", "2014010");
		// extract.put("c2014011", "2014011");
		// extract.put("c2014012", "2014012");
		// extract.put("c2015001", "2015001");
		// extract.put("c2015002", "2015002");
		// extract.put("c2015003", "2015003");
		// extract.put("c2015004", "2015004");
		// extract.put("c2015005", "2015005");
		// extract.put("c2015006", "2015006");
		// extract.put("c2015007", "2015007");
		// extract.put("c2015008", "2015008");
		// extract.put("c2015009", "2015009");
		// extract.put("c2015010", "2015010");
		// extract.put("c2015011", "2015011");
		// extract.put("c2015012", "2015012");
		// extract.put("c2016001", "2016001");
		// extract.put("c2016002", "2016002");
		// extract.put("c2016003", "2016003");
		// extract.put("c2016004", "2016004");
		// extract.put("c2016005", "2016005");
		// extract.put("c2016006", "2016006");
		// extract.put("c2016007", "2016007");
		// extract.put("c2016008", "2016008");
		// extract.put("c2016009", "2016009");
		// extract.put("c2016010", "2016010");
		// extract.put("c2016011", "2016011");
		// extract.put("c2016012", "2016012");

		// DataModelResult result10 = dm.getResult(query, extract,
		// features);
		// DataModelResult result11 = dm.getResult(query, extract,
		// features1);
		// final Iterator<DBObject> iterator3 = result11.iterator();
		// Job j1 = new Job("result11") {
		//
		// @Override
		// protected IStatus run(IProgressMonitor monitor) {
		// while (iterator3.hasNext()) {
		// DBObject next = iterator3.next();
		// System.out.println("result3" + next);
		// }
		// return Status.OK_STATUS;
		// }
		// };
		// final Iterator<DBObject> iterator = result10.iterator();
		// Job j2 = new Job("result10") {
		//
		// @Override
		// protected IStatus run(IProgressMonitor monitor) {
		// while (iterator.hasNext()) {
		// DBObject dbObject = (DBObject) iterator.next();
		// System.out.println("result" + dbObject);
		// }
		// return Status.OK_STATUS;
		// }
		// };
		// j1.schedule();
		// j2.schedule();
		// end = System.currentTimeMillis();
		//
		// System.out.println("" + (end - start));
		// } catch (Exception e) {
		// // TODO Auto-generated catch block
		// e.printStackTrace();
		// }

		// //
		// List<DBObject> features1 = getFeature();
		//
		// List<String> feature = new ArrayList<String>();
		// feature.add("dept");
		// // feature.add("market");
		//
		// String values = "amount";
		//
		// DBObject extract1 = new BasicDBObject();
		// extract1.put("columName", "datecode");
		// DBObject extractlist = new BasicDBObject();
		//
		// extract1.put("list", extractlist);
		//
		// long start, end;
		// start = System.currentTimeMillis();
		// DBCollection col = getCol("omsalesincome");
		// String map = "function Map() {";
		// map += "emit({";
		// for (int i = 0; i < feature.size(); i++) {
		// map += feature.get(i) + ":this." + feature.get(i);
		// if (i < feature.size() - 1) {
		// map += ",";
		// }
		// }
		// map += "}";
		// map += ",{";
		// DBObject obj = (DBObject) extract1.get("list");
		// for (String key : obj.keySet()) {
		// map += key + ":this." + values + ",";
		// }
		//
		// map += values + ":this." + values + "," + extract1.get("columName")
		// + ":this." + extract1.get("columName") + "})";
		//
		// map += "}";
		// String reduce = "function Reduce(key, values)" + "{"
		// + "var reduced = {";
		// for (String key : obj.keySet()) {
		// reduce += key + ":0,";
		// }
		//
		// reduce += values + ":0};";
		// reduce += "values.forEach(function(val) " + "{";
		// for (String key : obj.keySet()) {
		// Object object = obj.get(key);
		//
		// reduce += "if(" + object + "" + " || typeof(val."
		// + extract1.get("columName")
		// + ") == \"undefined\"){ reduced." + key + " += val." + key
		// + ";};";
		// }
		// reduce += "reduced." + values + " += val." + values + ";" + "});"
		// + "return reduced;" + "}";
		// // String finalize;
		// // String outputCollection;
		// MapReduceCommand mapReduceCommand = new MapReduceCommand(col, map,
		// reduce, "omsalesincomes", MapReduceCommand.OutputType.INLINE,
		// null);
		// // mapReduceCommand.setFinalize(finalize);
		// List<DBObject> data = new ArrayList<DBObject>();
		// MapReduceOutput mapReduce = col.mapReduce(mapReduceCommand);
		// for (DBObject dbo : mapReduce.results()) {
		// DBObject value = (DBObject) dbo.get("_id");
		// value.putAll((DBObject) dbo.get("value"));
		// data.add(value);
		// }
		// List<DBObject> result1 = getResult(features1, data, feature);
		// end = System.currentTimeMillis();
		//
		// System.out.println("" + (end - start));
		// print(result1);
	}

	private void printResult(DataSet ds, String name) throws Exception {
//		DBObject result = ds.build(null);
//		Commons.loginfo(name + ">>" + result);
	}

	// @SuppressWarnings("unchecked")
	// private void print(List<DBObject> result) {
	// for (DBObject dbo : result) {
	// Commons.loginfo(dbo.toString());
	// List<DBObject> children = (List<DBObject>) dbo.get("children");
	// if (children != null && children.size() > 0) {
	// Commons.loginfo("children start");
	// print(children);
	// Commons.loginfo("children end");
	// }
	// }
	// }
	//
	// private List<DBObject> getFeature() {
	// List<DBObject> result = new ArrayList<DBObject>();
	// DBCollection orgCol = getCol(IModelConstants.C_ORGANIZATION);
	// DBObject orgdbo = orgCol.findOne(
	// new BasicDBObject().append(Organization.F_PARENT_ID, null),
	// new BasicDBObject().append("_id", 1));
	// Organization org = ModelService.createModelObject(orgdbo,
	// Organization.class);
	// orgdbo.put("dept", orgdbo.get("_id"));
	// List<DBObject> childrenFeature = getChildrenFeature(org.get_id());
	// if (childrenFeature != null) {
	// orgdbo.put("children", childrenFeature);
	// }
	// result.add(orgdbo);
	// return result;
	//
	// }
	//
	// private List<DBObject> getChildrenFeature(ObjectId id) {
	// Organization org = ModelService.createModelObject(Organization.class,
	// id);
	// List<ObjectId> childrenOrg = org.getChildrenOrganizationId(null);
	// if (childrenOrg != null && childrenOrg.size() > 0) {
	// List<DBObject> result = new ArrayList<DBObject>();
	// for (ObjectId _id : childrenOrg) {
	// DBObject data = new BasicDBObject();
	// data.put("dept", _id);
	// data.put("_id", _id);
	// List<DBObject> childrenFeature = getChildrenFeature(_id);
	// if (childrenFeature != null) {
	// data.put("children", childrenFeature);
	// }
	// result.add(data);
	// }
	// return result;
	// }
	// return null;
	// }
	//
	// private List<DBObject> getResult(List<DBObject> features,
	// List<DBObject> data, List<String> feature) {
	// List<DBObject> result = new ArrayList<DBObject>();
	// for (DBObject dbo : features) {
	// for (DBObject dataDBO : data) {
	// boolean b = true;
	// for (String key : feature) {
	// if (!dbo.get(key).equals(dataDBO.get(key))) {
	// b = false;
	// }
	// }
	// if (b) {
	// dbo.putAll(dataDBO);
	// }
	// }
	// List<DBObject> children = (List<DBObject>) dbo.get("children");
	// if (children != null && children.size() > 0) {
	// List<DBObject> result2 = getResult(children, data, feature);
	// dbo.put("children", result2);
	// }
	// result.add(dbo);
	// }
	//
	// return result;
	// }
	//
	// private DBCollection getCol(String collectionName) {
	// return DBActivator.getCollection(IModelConstants.DB, collectionName);
	// }
}
